﻿using SuperSocket.Facility.Protocol;//
using SuperSocket.Common;
using SuperSocket.SocketBase.Protocol;
using System;//

namespace TcpServer.OUServer
{
    public class OUServerProtocolReceiveFilter : FixedHeaderReceiveFilter<OUServerProtocolRequestInfo>
    {
        /*
         * OUServer控制器       = 2字节 为包头，固定为OUServer控制器85 5A
            DTYPE       = 设备类型, 1字节, OUServer控制器 固定为 0
            DAddr       = 设备地址, 4字节, 如地址为 999(0x3E7), DAddr = 0xE7 0x03 0x00 0x00
            seq                 = 帧序号, 2字节, 为帧序列号
            Len         = 长度,2字节,  为 C 到 CS(包含)的长度
            C 为控制码，最高位为0表示主动发出方，最高位为1表示 回复方 1字节
            Addr              = 为地址，2字节, 如地址是 123 (0x7B) ,Addr = 0x7B 0x00
            DLen(2Byte) = 为 Data 的长度
            Data 不定长度
            CS 为 85 + 5A + Num0 + ... + Data 最后1个字节 的 8位数(高位舍弃)的校验和
         */

        public OUServerProtocolReceiveFilter()
            : base(16)
        {
            //2+1+4+2+2+1+2+2 =16
        }

        protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
        {
            //length为base(6)的6
            //获取高位
            byte high = header[offset + length - 1];
            //获取低位
            byte low = header[offset + length - 2];
            int len = (int)high * 256 + low;
            return len + 1;//结尾有1个字节(CS)
        }

        protected override OUServerProtocolRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
        {
            //BinaryRequestInfo res = new BinaryRequestInfo(BytesToHexStr(header.Array), bodyBuffer.CloneRange(offset, length));
            string entireFrame = BytesToHexStr(header.Array) + BytesToHexStr(bodyBuffer.CloneRange(offset, length));
            OUServerProtocolRequestInfo info = new OUServerProtocolRequestInfo();
            info.DTYPE = entireFrame.Substring(4, 2 * 1);
            info.DAddr = entireFrame.Substring(6, 2 * 4);
            info.DAddrReverse= HEXtoDEC(ReverseHexString(info.DAddr));
            info.seq = entireFrame.Substring(14, 2 * 2);
            info.seqDec = int.Parse(HEXtoDEC(ReverseHexString(info.seq)));
            info.Len = entireFrame.Substring(18, 2 * 2);
            info.LenDec = int.Parse(HEXtoDEC(ReverseHexString(info.Len)));
            info.C = entireFrame.Substring(22, 2 * 1);
            info.Addr = entireFrame.Substring(24, 2 * 2);
            info.AddrDec = int.Parse(HEXtoDEC(ReverseHexString(info.Addr)));
            info.DLen = entireFrame.Substring(28, 2 * 2);
            info.DLenDec = int.Parse(HEXtoDEC(ReverseHexString(info.DLen)));
            info.Data = entireFrame.Substring(32, 2 * info.DLenDec);
            info.CS = entireFrame.Substring(32+ 2 * info.DLenDec, 2);
            info.EntireFrame = entireFrame;
            return info;
        }

        /// <summary>
        /// 转化bytes成16进制的字符
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        private string BytesToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }

        /// <summary>
        /// 高低对调
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        string ReverseHexString(string str)
        {
            char[] buff = new char[str.Length];
            for (int i = 0; i < str.Length; i += 2)
            {
                buff[i] = str[str.Length - i - 2];
                buff[i + 1] = str[str.Length - 1 - i];
            }
            string s = new string(buff);
            return s;
        }

        /// <summary>
        /// 16进制转10进制
        /// </summary>
        /// <param name="HEX"></param>
        /// <returns></returns>
        string HEXtoDEC(string HEX)
        {
            return Convert.ToInt64(HEX, 16).ToString();
        }
    }
}
